package engine.video.palette;

import engine.Constants;

public class Palette {
	public Palette() {
		_Data = new int[Constants.PALETTE_ENTRIES];
	}
	public Palette(int[] colorRGB) {
		if (colorRGB == null) {
			_Data = new int[Constants.PALETTE_ENTRIES];
		} else {
			_Data = colorRGB.clone(); // create a copy of the palette.
		}
	}
	public void setPalette(int index, int colorRGB) {
		if (index < 0 || index >= _Data.length) {
			throw new ArrayIndexOutOfBoundsException();
		}
		_Data[index] = colorRGB;
	}
	public int[] getEntries() {
		return _Data;
	}
	/**
	 * @param r - Red component
	 * @param g - Green component
	 * @param b - Blue component
	 * @returns the index of the color in this palette that most closely matches the give 24bit color.
	 **/
	public int getIndexofColor(int r, int g, int b) {
		int pr, pg, pb; // palette components
		int rr, gr, br; // ratings
		int color;		// palette color
		int bestIndex = 0;
		int bestRating = 1000;
		int rating;		// rating of the test color
		
		
		for(int i = 0; i < _Data.length; i++) {
			color = _Data[i];
			// extract color components
			pr = (color >> 0x10) & 0xFF;
			pg = (color >> 0x08) & 0xFF;
			pb = (color) & 0xFF;
			
			// compare the input components with the color components
			rr = pr - r;
			gr = pg - g;
			br = pb - b;
			
			// find deviation
			rating = Math.abs(rr + gr + br);
			if(rating == 0) { // Match!
				return i;
			}
			if(rating < bestRating) {
				bestRating = rating;
				bestIndex = i;
			}
		}
		return bestIndex;
	}

	private int[] _Data;
	
	// Static Helpers ----------------------------------------------------------
	
	public static Palette generatePaletteIRGB() {
		
		Palette p = new Palette();
		int color = 0;
        byte f = (byte)(256 / 3);
        int i, r, g, b;
        float div;
        int c;
        for (c = 0; c < 256; c++)
        {

            i = (byte)((c >> 6) & 0x3);
            div = (i + 1) * 0.25f;
            r = (byte)((((c >> 4) & 0x3) * f) * (div));
            g = (byte)((((c >> 2) & 0x3) * f) * (div));
            b = (byte)((((c) & 0x3) * f) * (div));
            color = (r << 0x10) | (g << 0x08) | b;
            p.setPalette(c, color);
        }
        return p;
	}
}
